﻿#include "NodeModel.h"
// #include "_cfg.h"


bool NodeModel::init(Node* parentForLael, const cpp::sPointer& body, const string& name, const string& appelation)
{
	if (!parentForLael)
	{
		return false;
	}
	if (!Node::init())
	{
		return false;
	}
	if (!NodeSnatch::init(this))
	{
		return false;
	}

	_cascadeColorEnabled = true;
	_cascadeOpacityEnabled = true;

	parentForLael->addChild(_LabelAppelation = Label2::create(_appellation = appelation), 0xFFFFFF);
	parentForLael->addChild(_LabelName = Label2::create(_name = name), 0xFFFFFF);
	_LabelAppelation->setAnchorPoint(Vec2::ANCHOR_MIDDLE_TOP);
	_LabelAppelation->setColor(Color3B::BLUE);
	_LabelName->setAnchorPoint(Vec2::ANCHOR_MIDDLE_TOP);
	_LabelName->setColor(Color3B::GREEN);

//	this->addChild(_spriteShadow = Sprite2::create(cfg::getWdf171()->getPointer(UID_SHADOW)));
	this->addChild(_nodeFoot = Node::create());
	this->addChild(_nodeDown = Node::create());
	this->addChild(_nodeBody = Node::create());
	this->addChild(_nodeUp = Node::create());
	this->addChild(_nodeTopBlood = Node::create());
	this->addChild(_nodeTop = Node::create());
	
	_nodeBody->setCascadeColorEnabled(true);
	_nodeBody->setCascadeOpacityEnabled(true);


	addChildBody(body);
	scheduleUpdate();
	return true;
}

bool NodeModel::isBox(const Vec2& worldSpace)
{
	Sprite2* sprite = (Sprite2*)_nodeBody->getChildren().front();
	return sprite->isBox(worldSpace);
}

void NodeModel::setState(const eState& state)
{
	if (state == eState::Cross)
	{
		if (_isBlinking)
		{
			_isBlinkingWhenCrossing = true;
			setBlink(false);
		}
		setBodyYellow(true);
	}
	else
	{
		if (_isBlinkingWhenCrossing)
		{
			setBlink(true);
		}
		setBodyYellow(false);
	}
}

void NodeModel::doClick(const Vec2& location, bool isActiveForListener)
{
	if (!isActiveForListener)
	{
		return;
	}
	Vec2 v = _nodeBody->getChildren().front()->getPosition();
	v = _nodeBody->convertToWorldSpace(v);
	Director::getInstance()->getOpenGLView()->setViewName(toString("%0.f, %0.f", v.x, v.y));
}



void NodeModel::setDirection(const eDirection& direction)
{
	for (const auto& node : _nodeBody->getChildren())
	{
		Sprite2* sprite = (Sprite2*)node;
		sprite->setDirection(direction);
	}
	for (const auto& node : _nodeUp->getChildren())
	{
		Sprite2* sprite = (Sprite2*)node;
		sprite->setDirection(direction);
	}
	for (const auto& node : _nodeDown->getChildren())
	{
		Sprite2* sprite = (Sprite2*)node;
		sprite->setDirection(direction);
	}
}



void NodeModel::setBodyYellow(bool isYellow)
{
	
	if (_nodeBody)
	{
//		_nodeBody->setColor(isYellow ? Color3B(0xFF, 0xFF, 0x88) : Color3B::WHITE);
//		_nodeBody->setScale(isYellow ? 1.2f : 1);
// 		for (const auto& node : _nodeBody->getChildren())
// 		{
// 			Sprite2* sprite = (Sprite2*)node;
// 			sprite->setHighlight(isYellow);
// 		}
	}
}



void NodeModel::setBlink(bool isBlink)
{
	if (_isBlinking = isBlink)
	{
		if (!_actionBlinkYellow)
		{
			auto rep = [](){ return RepeatForever::create(Sequence::create(
				DelayTime::create(0.5f),
				CallFuncN::create([](Node* n){n->setColor(Color3B::YELLOW); }),
				DelayTime::create(0.5f),
				CallFuncN::create([](Node* n){n->setColor(Color3B::WHITE); }),
				nullptr)); };
			_nodeBody->runAction(_actionBlinkYellow = rep());
		}
	}
	else if (_actionBlinkYellow)
	{
		_nodeBody->stopAction(_actionBlinkYellow);
		_actionBlinkYellow = nullptr;
	}
}



void NodeModel::setNameColor(const Color3B& c)
{
	_LabelName->setColor(c);
}


void NodeModel::setNameColorRand(bool isActing)
{
	if (isActing && !_actionNameColorRand)
	{
		static RepeatForever* rep = RepeatForever::create(Sequence::create(
			CallFuncN::create([](Node* n){n->runAction(TintTo::create(0.5f, random(0, 0xff), random(0, 0xff), random(0, 0xff))); }),
			DelayTime::create(0.5f), nullptr));
		_LabelName->runAction(_actionNameColorRand = rep->clone());
	}
	else if (_actionNameColorRand)
	{
		_LabelName->stopAction(_actionNameColorRand);
		_actionNameColorRand = nullptr;
	}
	
}


Sprite2*  NodeModel::addChildBody(const cpp::sPointer& body)
{
	return addChildFromPointer(_nodeBody, body);
}

Sprite2*  NodeModel::addChildTop(const cpp::sPointer& top)
{
	return addChildFromPointer(_nodeTop, top);
}

Sprite2*  NodeModel::addChildTopBlood(const cpp::sPointer& topBlood)
{
	return addChildFromPointer(_nodeTopBlood, topBlood);
}

Sprite2*  NodeModel::addChildUp(const cpp::sPointer& up)
{
	return addChildFromPointer(_nodeUp, up);
}

Sprite2*  NodeModel::addChildDown(const cpp::sPointer& down)
{
	return addChildFromPointer(_nodeDown, down);
}

Sprite2*  NodeModel::addChildFoot(const cpp::sPointer& foot)
{
	return addChildFromPointer(_nodeFoot, foot);
}




Sprite2* NodeModel::addChildFromPointer(Node* node, const cpp::sPointer& pter)
{
	Sprite2* sprite = Sprite2::create(pter);
	node->addChild(sprite);
// 	node->setContentSize(sprite->getContentSize());
// 	node->setAnchorPoint(sprite->getAnchorPoint());
// 	sprite->setPosition(sprite->getAnchorPointInPoints());
	sprite->play(true);
	return sprite;
}



void NodeModel::update(float delta)
{
	static Vec2 v;
	v = getParent()->convertToWorldSpace(getPosition());
	v = _LabelAppelation->getParent()->convertToNodeSpace(v);
	static float h;
	h = _LabelName->getContentSize().height;
	_LabelAppelation->setPosition(v.x, v.y - h);
	_LabelName->setPosition(v.x, _LabelAppelation->getPositionY() - h);
}